//
// Created by WuYong on 2021/12/22.
//

#include "Sequence_Queue.h"

/*
 由于并不是循环队列，而且还是顺序队，缺点非常大，对内存空间的利用率很低
 不建议使用，要么链队，要么循环队列
 */

Status InitQueue(SqQueue *Q){

    Q->Head=(SElemType*) malloc(sizeof(SElemType)*QUEUE_INIT_SIZE); //给队分配初始空间
    if(!Q->Head) exit(OVERFLOW);    //储存分配失败
    //初始化队
    Q->Tail=Q->Head;
    Q->QueueSize=QUEUE_INIT_SIZE;
    return OK;
}  //构造一个空队


Status DestroyQueue(SqQueue *Q){
    if(Q==NULL) return ERROR;
    free(Q->Head);  //直接释放队的空间
    free(Q);    //释放队
    Q=NULL;
    return OK;
}    //销毁队Q，Q不再存在


Status ClearQueue(SqQueue *Q){
    if(Q==NULL||Q->Head==NULL) return ERROR;
    Q->Tail=Q->Head;    //直接将队头队尾合并，
    return OK;
}  //把Q置为空队


Status QueueEmpty(SqQueue Q){
    if(Q.Head==NULL)    return ERROR;
    if(Q.Head==Q.Tail)   return TRUE;
    else    return FALSE;
}   //若Q为空队返回TRUE，否则返回FALSE


int QueueLength(SqQueue Q){
    if(Q.Head==NULL)    return ERROR;
    return (int)(Q.Tail-Q.Head);
}     //返回Q的元素个数，即队的长度


SElemType* GetHead(SqQueue Q){
    SElemType *re;
    if(Q.Tail==Q.Head)   return NULL;
    re=(Q.Head);
    return re;
}  //若栈不空，则返回队顶元素，否则返回NULL


Status EnQueue(SqQueue *Q,SElemType e){
    if(Q->Tail-Q->Head>=Q->QueueSize){   //队满，追加存储空间
        Q->Head=(SElemType*) realloc(Q->Head,(Q->QueueSize+QUEUE_INCREMENT)* sizeof(SElemType));
        if(!Q->Head) exit(OVERFLOW);    //存储分配失败
        Q->Tail=Q->Head+Q->QueueSize;
        Q->QueueSize+=QUEUE_INCREMENT;
    }
    *Q->Tail++=e;
    return OK;
}    //插入元素e为新的队头元素


SElemType DeQueue(SqQueue *Q){
    SElemType re;
    if(Q->Tail==Q->Head) exit(ERROR);
    re=*(Q->Head);
    SElemType *tmp=Q->Head;
    for (int i = 0; tmp!=Q->Tail ; ++i) {
        *tmp=*(tmp+1);
        tmp=tmp+1;
    }
    Q->Tail--;
    return re;
}  //若栈不空，则删除队头元素并返回，否则返回NULL


Status QueueTraverse(SqQueue Q,Status (*visit)(SElemType)){
    if(Q.Head==NULL)    return ERROR;
    SElemType *tmp=Q.Head;
    for (int i = 0; tmp!=(Q.Tail) ; ++i) {
        visit(*tmp);
        tmp++;
    }
    return OK;
}     //从队尾到队头一次对队中每个元素调用函数visit（），一旦visit（）失败，则返回ERROR